package com.webapp.api.unicom;


import org.apache.commons.codec.binary.Base64;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * RSA 工具类
 *
 * @author jinxin
 * @since 2022/7/26 09:33
 */

public class RsaUtils {

    public static PublicKey getPublicKeyFromX509(String algorithm,
                                                 byte[] encodedKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
    }

    public static boolean rsaVerifyPublickey(String content, String sign,
                                             PublicKey pubKey, String charset) throws Exception {
        try {
            java.security.Signature signature = java.security.Signature
                    .getInstance("SHA1WithRSA");

            signature.initVerify(pubKey);

            if (charset == null || "".equals(charset)) {
                signature.update(content.getBytes());
            } else {
                signature.update(content.getBytes(charset));
            }

            return signature.verify(Base64.decodeBase64(sign.getBytes()));
        } catch (Exception e) {
            throw e;
        }
    }

    public static boolean rsaVerifyPublickey(String content, String sign,
                                             String publicKey, String charset) throws Exception {
        try {
            PublicKey pubKey = getPublicKeyFromX509("RSA",
                    Base64.decodeBase64(publicKey.getBytes()));
            return rsaVerifyPublickey(content, sign, pubKey, charset);
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("RSAcontent = " + content + ",sign=" + sign
                    + ",charset = " + charset, e);
        }
    }

    public static PrivateKey getPrivateKeyFromPKCS8(String algorithm, byte[] encodedKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
    }

    public static String rsaSign(String content, String privateKey, String charset) throws Exception {
        return rsaSign(content, java.util.Base64.getDecoder().decode(privateKey), charset);
    }

    /**
     * @param privateKey base64
     */
    public static String rsaSign(String content, byte[] privateKey, String charset) throws Exception {
        PrivateKey priKey = RsaUtils.getPrivateKeyFromPKCS8("RSA", privateKey);
        return rsaSign(content, priKey, charset);
    }

    public static String rsaSign(String content, PrivateKey priKey, String charset) throws Exception {
        java.security.Signature signature = java.security.Signature
                .getInstance("SHA1WithRSA");
        signature.initSign(priKey);
        if (charset == null || "".equals(charset)) {
            signature.update(content.getBytes());
        } else {
            signature.update(content.getBytes(charset));
        }
        byte[] signed = signature.sign();
        return new String(Base64.encodeBase64(signed));
    }

}
